import { DateObject, Period } from '../types/common';
import { UseCompare } from './types';
import { useDate } from './use-date';

export function useCompare(): UseCompare {
    const { getTimeInMilliseconds } = useDate();

    function isInitializedDate(date: DateObject): boolean {
        return date && date.year !== 0 && date.month !== 0 && date.day !== 0;
    }

    function isInitializedMonth(date: DateObject): boolean {
        return date && date.year !== 0 && date.month !== 0;
    }

    function isInitializedYear(date: DateObject): boolean {
        return date && date.year !== 0;
    }

    function isDateEarlier(firstDate: DateObject, secondDate: DateObject): boolean {
        return getTimeInMilliseconds(firstDate) < getTimeInMilliseconds(secondDate);
    }

    function equalOrEarlier(firstDate: DateObject, secondDate: DateObject): boolean {
        return getTimeInMilliseconds(firstDate) <= getTimeInMilliseconds(secondDate);
    }

    function equal(firstDate: DateObject, secondDate: DateObject): boolean {
        return getTimeInMilliseconds(firstDate) === getTimeInMilliseconds(secondDate);
    }

    function isPoint(period: Period, date: DateObject): boolean {
        const dateMs: number = getTimeInMilliseconds(date);
        return getTimeInMilliseconds(period.from) === dateMs || getTimeInMilliseconds(period.to) === dateMs;
    }

    function inPeriod(date: DateObject, period: Period | null): boolean {
        if (!period) {
            return false;
        }
        if (!isInitializedDate(period.to) || !isInitializedDate(period.from)) {
            return false;
        }
        return equalOrEarlier(period.from, date) && equalOrEarlier(date, period.to);
    }

    function isMonthDisabledByDisableSince(date: DateObject, disableSince: DateObject): boolean {
        return isInitializedDate(disableSince) && getTimeInMilliseconds(date) >= getTimeInMilliseconds(disableSince);
    }

    function isMonthDisabledByDisableUntil(date: DateObject, disableUntil: DateObject): boolean {
        return isInitializedDate(disableUntil) && getTimeInMilliseconds(date) <= getTimeInMilliseconds(disableUntil);
    }

    function sameDay(firstDate: DateObject, secondDate: DateObject): boolean {
        return (
            getTimeInMilliseconds({ year: firstDate.year, month: firstDate.month, day: firstDate.day }) ===
            getTimeInMilliseconds({ year: secondDate.year, month: secondDate.month, day: secondDate.day })
        );
    }

    function sameTime(firstDate: DateObject, secondDate: DateObject): boolean {
        return (
            getTimeInMilliseconds({ hour: firstDate.hour, minute: firstDate.minute, second: firstDate.second }) ===
            getTimeInMilliseconds({ hour: secondDate.hour, minute: secondDate.minute, second: secondDate.second })
        );
    }

    return {
        isDateEarlier,
        equal,
        inPeriod,
        isPoint,
        equalOrEarlier,
        isInitializedDate,
        isInitializedMonth,
        isInitializedYear,
        isMonthDisabledByDisableSince,
        isMonthDisabledByDisableUntil,
        sameTime,
        sameDay
    };
}
